package com.yhh.college_information_platform.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yhh.college_information_platform.common.PageResult;
import com.yhh.college_information_platform.common.ResultCode;
import com.yhh.college_information_platform.dto.NotificationQueryDTO;
import com.yhh.college_information_platform.entity.Notification;
import com.yhh.college_information_platform.entity.Resource;
import com.yhh.college_information_platform.entity.User;
import com.yhh.college_information_platform.exception.BusinessException;
import com.yhh.college_information_platform.mapper.NotificationMapper;
import com.yhh.college_information_platform.mapper.ResourceMapper;
import com.yhh.college_information_platform.mapper.UserMapper;
import com.yhh.college_information_platform.service.NotificationService;
import com.yhh.college_information_platform.vo.NotificationVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 消息通知服务实现类
 */
@Service
public class NotificationServiceImpl implements NotificationService {
    
    @Autowired
    private NotificationMapper notificationMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private ResourceMapper resourceMapper;
    
    // 通知类型描述映射
    private static final Map<String, String> TYPE_DESC_MAP = new HashMap<>();
    
    static {
        TYPE_DESC_MAP.put("COMMENT", "评论通知");
        TYPE_DESC_MAP.put("REPLY", "回复通知");
        TYPE_DESC_MAP.put("AUDIT", "审核通知");
        TYPE_DESC_MAP.put("SYSTEM", "系统通知");
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendCommentNotification(Long resourceId, String resourceTitle, Long receiverId,
                                       Long senderId, String senderName, String commentContent) {
        // 不给自己发通知
        if (receiverId.equals(senderId)) {
            return;
        }
        
        Notification notification = new Notification();
        notification.setReceiverId(receiverId);
        notification.setSenderId(senderId);
        notification.setType("COMMENT");
        notification.setTitle("新评论通知");
        notification.setContent(senderName + " 评论了你的资料：" + truncateContent(commentContent, 50));
        notification.setResourceId(resourceId);
        notification.setIsRead(0);
        
        notificationMapper.insert(notification);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendReplyNotification(Long resourceId, String resourceTitle, Long commentId,
                                     Long receiverId, Long senderId, String senderName, String replyContent) {
        // 不给自己发通知
        if (receiverId.equals(senderId)) {
            return;
        }
        
        Notification notification = new Notification();
        notification.setReceiverId(receiverId);
        notification.setSenderId(senderId);
        notification.setType("REPLY");
        notification.setTitle("新回复通知");
        notification.setContent(senderName + " 回复了你的评论：" + truncateContent(replyContent, 50));
        notification.setResourceId(resourceId);
        notification.setCommentId(commentId);
        notification.setIsRead(0);
        
        notificationMapper.insert(notification);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendAuditNotification(Long resourceId, String resourceTitle, Long receiverId,
                                     Boolean isApproved, String rejectReason) {
        Notification notification = new Notification();
        notification.setReceiverId(receiverId);
        notification.setSenderId(null); // 系统发送
        notification.setType("AUDIT");
        notification.setResourceId(resourceId);
        notification.setIsRead(0);
        
        if (isApproved) {
            notification.setTitle("资料审核通过");
            notification.setContent("你的资料《" + resourceTitle + "》已审核通过");
        } else {
            notification.setTitle("资料审核未通过");
            String reason = StrUtil.isNotBlank(rejectReason) ? rejectReason : "不符合平台规范";
            notification.setContent("你的资料《" + resourceTitle + "》审核未通过，原因：" + reason);
        }
        
        notificationMapper.insert(notification);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendSystemNotification(Long receiverId, String title, String content) {
        if (receiverId == null) {
            // 全员通知：查询所有用户
            List<User> allUsers = userMapper.selectList(new LambdaQueryWrapper<User>()
                .eq(User::getStatus, 1)); // 只给正常状态的用户发送
            
            for (User user : allUsers) {
                Notification notification = new Notification();
                notification.setReceiverId(user.getId());
                notification.setSenderId(null);
                notification.setType("SYSTEM");
                notification.setTitle(title);
                notification.setContent(content);
                notification.setIsRead(0);
                notificationMapper.insert(notification);
            }
        } else {
            // 单个用户通知
            Notification notification = new Notification();
            notification.setReceiverId(receiverId);
            notification.setSenderId(null);
            notification.setType("SYSTEM");
            notification.setTitle(title);
            notification.setContent(content);
            notification.setIsRead(0);
            notificationMapper.insert(notification);
        }
    }
    
    @Override
    public PageResult<NotificationVO> getNotificationList(Long userId, NotificationQueryDTO queryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<Notification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Notification::getReceiverId, userId);
        
        if (queryDTO.getIsRead() != null) {
            wrapper.eq(Notification::getIsRead, queryDTO.getIsRead());
        }
        
        if (StrUtil.isNotBlank(queryDTO.getType())) {
            wrapper.eq(Notification::getType, queryDTO.getType());
        }
        
        wrapper.orderByDesc(Notification::getCreateTime);
        
        // 分页查询
        Page<Notification> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        Page<Notification> resultPage = notificationMapper.selectPage(page, wrapper);
        
        // 转换为VO
        List<NotificationVO> voList = resultPage.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
        
        return new PageResult<NotificationVO>(voList, resultPage.getTotal(), resultPage.getCurrent(), resultPage.getSize());
    }
    
    @Override
    public Long getUnreadCount(Long userId) {
        LambdaQueryWrapper<Notification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Notification::getReceiverId, userId)
               .eq(Notification::getIsRead, 0);
        return notificationMapper.selectCount(wrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markAsRead(Long notificationId, Long userId) {
        // 查询通知
        Notification notification = notificationMapper.selectById(notificationId);
        if (notification == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "通知不存在");
        }
        
        // 验证是否是该用户的通知
        if (!notification.getReceiverId().equals(userId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "无权操作");
        }
        
        // 标记为已读
        if (notification.getIsRead() == 0) {
            notification.setIsRead(1);
            notification.setReadTime(LocalDateTime.now());
            notificationMapper.updateById(notification);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markAllAsRead(Long userId) {
        // 查询所有未读通知
        LambdaQueryWrapper<Notification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Notification::getReceiverId, userId)
               .eq(Notification::getIsRead, 0);
        
        List<Notification> unreadList = notificationMapper.selectList(wrapper);
        
        // 批量更新为已读
        LocalDateTime now = LocalDateTime.now();
        for (Notification notification : unreadList) {
            notification.setIsRead(1);
            notification.setReadTime(now);
            notificationMapper.updateById(notification);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteNotification(Long notificationId, Long userId) {
        // 查询通知
        Notification notification = notificationMapper.selectById(notificationId);
        if (notification == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "通知不存在");
        }
        
        // 验证是否是该用户的通知
        if (!notification.getReceiverId().equals(userId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "无权操作");
        }
        
        // 删除通知
        notificationMapper.deleteById(notificationId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void clearReadNotifications(Long userId) {
        LambdaQueryWrapper<Notification> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Notification::getReceiverId, userId)
               .eq(Notification::getIsRead, 1);
        
        notificationMapper.delete(wrapper);
    }
    
    /**
     * 转换为VO对象
     */
    private NotificationVO convertToVO(Notification notification) {
        NotificationVO vo = new NotificationVO();
        vo.setId(notification.getId());
        vo.setType(notification.getType());
        vo.setTypeDesc(TYPE_DESC_MAP.get(notification.getType()));
        vo.setTitle(notification.getTitle());
        vo.setContent(notification.getContent());
        vo.setResourceId(notification.getResourceId());
        vo.setCommentId(notification.getCommentId());
        vo.setIsRead(notification.getIsRead());
        vo.setCreateTime(notification.getCreateTime());
        vo.setReadTime(notification.getReadTime());
        
        // 获取发送者信息
        if (notification.getSenderId() != null) {
            User sender = userMapper.selectById(notification.getSenderId());
            if (sender != null) {
                vo.setSenderName(sender.getNickname());
                vo.setSenderAvatar(sender.getAvatar());
            }
        } else {
            vo.setSenderName("系统");
            vo.setSenderAvatar(null);
        }
        
        // 获取资源标题
        if (notification.getResourceId() != null) {
            Resource resource = resourceMapper.selectById(notification.getResourceId());
            if (resource != null) {
                vo.setResourceTitle(resource.getTitle());
            }
        }
        
        return vo;
    }
    
    /**
     * 截断内容
     */
    private String truncateContent(String content, int maxLength) {
        if (StrUtil.isBlank(content)) {
            return "";
        }
        if (content.length() <= maxLength) {
            return content;
        }
        return content.substring(0, maxLength) + "...";
    }
}

